{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 向量化和广播\n",
    "\n",
    "向量化和广播这两个概念是 numpy 内部实现的基础。有了向量化，编写代码时无需使用显式循环。这些循环实际上不能省略，只不过是在内部实现，被代码中的其他结构代替。向量化的应用使得代码更简洁，可读性更强，也可以说使用了向量化方法的代码看上去更“Pythonic”。\n",
    "\n",
    "广播（Broadcasting）机制描述了 numpy 如何在算术运算期间处理具有不同形状的数组，让较小的数组在较大的数组上“广播”，以便它们具有兼容的形状。并不是所有的维度都要彼此兼容才符合广播机制的要求，但它们必须满足一定的条件。\n",
    "\n",
    "若两个数组的各维度兼容，也就是两个数组的每一维等长，或其中一个数组为 一维，那么广播机制就适用。如果这两个条件不满足，numpy就会抛出异常，说两个数组不兼容。\n",
    "\n",
    "总结来说，广播的规则有三个：\n",
    "- 如果两个数组的维度数dim不相同，那么小维度数组的形状将会在左边补1。\n",
    "- 如果shape维度不匹配，但是有维度是1，那么可以扩展维度是1的维度匹配另一个数组；\n",
    "- 如果shape维度不匹配，但是没有任何一个维度是1，则匹配引发错误；\n",
    "\n",
    "【例】二维数组加一维数组\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(4)\n",
    "y = np.ones((3, 4))\n",
    "print(x.shape)  # (4,)\n",
    "print(y.shape)  # (3, 4)\n",
    "\n",
    "print((x + y).shape)  # (3, 4)\n",
    "print(x + y)\n",
    "# [[1. 2. 3. 4.]\n",
    "#  [1. 2. 3. 4.]\n",
    "#  [1. 2. 3. 4.]]\n",
    "```\n",
    "\n",
    "\n",
    "【例】两个数组均需要广播\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(4).reshape(4, 1)\n",
    "y = np.ones(5)\n",
    "\n",
    "print(x.shape)  # (4, 1)\n",
    "print(y.shape)  # (5,)\n",
    "\n",
    "print((x + y).shape)  # (4, 5)\n",
    "print(x + y)\n",
    "# [[1. 1. 1. 1. 1.]\n",
    "#  [2. 2. 2. 2. 2.]\n",
    "#  [3. 3. 3. 3. 3.]\n",
    "#  [4. 4. 4. 4. 4.]]\n",
    "\n",
    "x = np.array([0.0, 10.0, 20.0, 30.0])\n",
    "y = np.array([1.0, 2.0, 3.0])\n",
    "z = x[:, np.newaxis] + y\n",
    "print(z)\n",
    "# [[ 1.  2.  3.]\n",
    "#  [11. 12. 13.]\n",
    "#  [21. 22. 23.]\n",
    "#  [31. 32. 33.]]\n",
    "```\n",
    "\n",
    "【例】不匹配报错的例子\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(4)\n",
    "y = np.ones(5)\n",
    "\n",
    "print(x.shape)  # (4,)\n",
    "print(y.shape)  # (5,)\n",
    "\n",
    "print(x + y)\n",
    "# ValueError: operands could not be broadcast together with shapes (4,) (5,) \n",
    "```\n",
    "\n",
    "\n",
    "---\n",
    "# 数学函数\n",
    "\n",
    "\n",
    "## 算数运算\n",
    "### numpy.add\n",
    "### numpy.subtract\n",
    "### numpy.multiply\n",
    "### numpy.divide\n",
    "### numpy.floor_divide\n",
    "### numpy.power\n",
    "- `numpy.add(x1, x2, *args, **kwargs)` Add arguments element-wise.\n",
    "- `numpy.subtract(x1, x2, *args, **kwargs)` Subtract arguments element-wise.\n",
    "- `numpy.multiply(x1, x2, *args, **kwargs)` Multiply arguments element-wise.\n",
    "- `numpy.divide(x1, x2, *args, **kwargs)` Returns a true division of the inputs, element-wise.\n",
    "- `numpy.floor_divide(x1, x2, *args, **kwargs)` Return the largest integer smaller or equal to the division of the inputs.\n",
    "- `numpy.power(x1, x2, *args, **kwargs)` First array elements raised to powers from second array, element-wise.\n",
    "\n",
    "在 numpy 中对以上函数进行了运算符的重载，且运算符为 **元素级**。也就是说，它们只用于位置相同的元素之间，所得到的运算结果组成一个新的数组。\n",
    "\n",
    "【例】注意 numpy 的广播规则。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n",
    "y = x + 1\n",
    "print(y)\n",
    "print(np.add(x, 1))\n",
    "# [2 3 4 5 6 7 8 9]\n",
    "\n",
    "y = x - 1\n",
    "print(y)\n",
    "print(np.subtract(x, 1))\n",
    "# [0 1 2 3 4 5 6 7]\n",
    "\n",
    "y = x * 2\n",
    "print(y)\n",
    "print(np.multiply(x, 2))\n",
    "# [ 2  4  6  8 10 12 14 16]\n",
    "\n",
    "y = x / 2\n",
    "print(y)\n",
    "print(np.divide(x, 2))\n",
    "# [0.5 1.  1.5 2.  2.5 3.  3.5 4. ]\n",
    "\n",
    "y = x // 2\n",
    "print(y)\n",
    "print(np.floor_divide(x, 2))\n",
    "# [0 1 1 2 2 3 3 4]\n",
    "\n",
    "y = x ** 2\n",
    "print(y)\n",
    "print(np.power(x, 2))\n",
    "# [ 1  4  9 16 25 36 49 64]\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "【例】注意 numpy 的广播规则。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = x + 1\n",
    "print(y)\n",
    "print(np.add(x, 1))\n",
    "# [[12 13 14 15 16]\n",
    "#  [17 18 19 20 21]\n",
    "#  [22 23 24 25 26]\n",
    "#  [27 28 29 30 31]\n",
    "#  [32 33 34 35 36]]\n",
    "\n",
    "y = x - 1\n",
    "print(y)\n",
    "print(np.subtract(x, 1))\n",
    "# [[10 11 12 13 14]\n",
    "#  [15 16 17 18 19]\n",
    "#  [20 21 22 23 24]\n",
    "#  [25 26 27 28 29]\n",
    "#  [30 31 32 33 34]]\n",
    "\n",
    "y = x * 2\n",
    "print(y)\n",
    "print(np.multiply(x, 2))\n",
    "# [[22 24 26 28 30]\n",
    "#  [32 34 36 38 40]\n",
    "#  [42 44 46 48 50]\n",
    "#  [52 54 56 58 60]\n",
    "#  [62 64 66 68 70]]\n",
    "\n",
    "y = x / 2\n",
    "print(y)\n",
    "print(np.divide(x, 2))\n",
    "# [[ 5.5  6.   6.5  7.   7.5]\n",
    "#  [ 8.   8.5  9.   9.5 10. ]\n",
    "#  [10.5 11.  11.5 12.  12.5]\n",
    "#  [13.  13.5 14.  14.5 15. ]\n",
    "#  [15.5 16.  16.5 17.  17.5]]\n",
    "\n",
    "y = x // 2\n",
    "print(y)\n",
    "print(np.floor_divide(x, 2))\n",
    "# [[ 5  6  6  7  7]\n",
    "#  [ 8  8  9  9 10]\n",
    "#  [10 11 11 12 12]\n",
    "#  [13 13 14 14 15]\n",
    "#  [15 16 16 17 17]]\n",
    "\n",
    "y = x ** 2\n",
    "print(y)\n",
    "print(np.power(x, 2))\n",
    "# [[ 121  144  169  196  225]\n",
    "#  [ 256  289  324  361  400]\n",
    "#  [ 441  484  529  576  625]\n",
    "#  [ 676  729  784  841  900]\n",
    "#  [ 961 1024 1089 1156 1225]]\n",
    "```\n",
    "\n",
    "【例】注意 numpy 的广播规则。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "\n",
    "y = np.arange(1, 6)\n",
    "print(y)\n",
    "# [1 2 3 4 5]\n",
    "\n",
    "z = x + y\n",
    "print(z)\n",
    "print(np.add(x, y))\n",
    "# [[12 14 16 18 20]\n",
    "#  [17 19 21 23 25]\n",
    "#  [22 24 26 28 30]\n",
    "#  [27 29 31 33 35]\n",
    "#  [32 34 36 38 40]]\n",
    "\n",
    "z = x - y\n",
    "print(z)\n",
    "print(np.subtract(x, y))\n",
    "# [[10 10 10 10 10]\n",
    "#  [15 15 15 15 15]\n",
    "#  [20 20 20 20 20]\n",
    "#  [25 25 25 25 25]\n",
    "#  [30 30 30 30 30]]\n",
    "\n",
    "z = x * y\n",
    "print(z)\n",
    "print(np.multiply(x, y))\n",
    "# [[ 11  24  39  56  75]\n",
    "#  [ 16  34  54  76 100]\n",
    "#  [ 21  44  69  96 125]\n",
    "#  [ 26  54  84 116 150]\n",
    "#  [ 31  64  99 136 175]]\n",
    "\n",
    "z = x / y\n",
    "print(z)\n",
    "print(np.divide(x, y))\n",
    "# [[11.          6.          4.33333333  3.5         3.        ]\n",
    "#  [16.          8.5         6.          4.75        4.        ]\n",
    "#  [21.         11.          7.66666667  6.          5.        ]\n",
    "#  [26.         13.5         9.33333333  7.25        6.        ]\n",
    "#  [31.         16.         11.          8.5         7.        ]]\n",
    "\n",
    "z = x // y\n",
    "print(z)\n",
    "print(np.floor_divide(x, y))\n",
    "# [[11  6  4  3  3]\n",
    "#  [16  8  6  4  4]\n",
    "#  [21 11  7  6  5]\n",
    "#  [26 13  9  7  6]\n",
    "#  [31 16 11  8  7]]\n",
    "\n",
    "z = x ** np.full([1, 5], 2)\n",
    "print(z)\n",
    "print(np.power(x, np.full([5, 5], 2)))\n",
    "# [[ 121  144  169  196  225]\n",
    "#  [ 256  289  324  361  400]\n",
    "#  [ 441  484  529  576  625]\n",
    "#  [ 676  729  784  841  900]\n",
    "#  [ 961 1024 1089 1156 1225]]\n",
    "```\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "\n",
    "y = np.arange(1, 26).reshape([5, 5])\n",
    "print(y)\n",
    "# [[ 1  2  3  4  5]\n",
    "#  [ 6  7  8  9 10]\n",
    "#  [11 12 13 14 15]\n",
    "#  [16 17 18 19 20]\n",
    "#  [21 22 23 24 25]]\n",
    "\n",
    "z = x + y\n",
    "print(z)\n",
    "print(np.add(x, y))\n",
    "# [[12 14 16 18 20]\n",
    "#  [22 24 26 28 30]\n",
    "#  [32 34 36 38 40]\n",
    "#  [42 44 46 48 50]\n",
    "#  [52 54 56 58 60]]\n",
    "\n",
    "z = x - y\n",
    "print(z)\n",
    "print(np.subtract(x, y))\n",
    "# [[10 10 10 10 10]\n",
    "#  [10 10 10 10 10]\n",
    "#  [10 10 10 10 10]\n",
    "#  [10 10 10 10 10]\n",
    "#  [10 10 10 10 10]]\n",
    "\n",
    "z = x * y\n",
    "print(z)\n",
    "print(np.multiply(x, y))\n",
    "# [[ 11  24  39  56  75]\n",
    "#  [ 96 119 144 171 200]\n",
    "#  [231 264 299 336 375]\n",
    "#  [416 459 504 551 600]\n",
    "#  [651 704 759 816 875]]\n",
    "\n",
    "z = x / y\n",
    "print(z)\n",
    "print(np.divide(x, y))\n",
    "# [[11.          6.          4.33333333  3.5         3.        ]\n",
    "#  [ 2.66666667  2.42857143  2.25        2.11111111  2.        ]\n",
    "#  [ 1.90909091  1.83333333  1.76923077  1.71428571  1.66666667]\n",
    "#  [ 1.625       1.58823529  1.55555556  1.52631579  1.5       ]\n",
    "#  [ 1.47619048  1.45454545  1.43478261  1.41666667  1.4       ]]\n",
    "\n",
    "z = x // y\n",
    "print(z)\n",
    "print(np.floor_divide(x, y))\n",
    "# [[11  6  4  3  3]\n",
    "#  [ 2  2  2  2  2]\n",
    "#  [ 1  1  1  1  1]\n",
    "#  [ 1  1  1  1  1]\n",
    "#  [ 1  1  1  1  1]]\n",
    "\n",
    "z = x ** np.full([5, 5], 2)\n",
    "print(z)\n",
    "print(np.power(x, np.full([5, 5], 2)))\n",
    "# [[ 121  144  169  196  225]\n",
    "#  [ 256  289  324  361  400]\n",
    "#  [ 441  484  529  576  625]\n",
    "#  [ 676  729  784  841  900]\n",
    "#  [ 961 1024 1089 1156 1225]]\n",
    "```\n",
    "\n",
    "### numpy.sqrt\n",
    "### numpy.square\n",
    "- `numpy.sqrt(x, *args, **kwargs)` Return the non-negative square-root of an array, element-wise.\n",
    "- `numpy.square(x, *args, **kwargs)` Return the element-wise square of the input.\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(1, 5)\n",
    "print(x)  # [1 2 3 4]\n",
    "\n",
    "y = np.sqrt(x)\n",
    "print(y)\n",
    "# [1.         1.41421356 1.73205081 2.        ]\n",
    "print(np.power(x, 0.5))\n",
    "# [1.         1.41421356 1.73205081 2.        ]\n",
    "\n",
    "y = np.square(x)\n",
    "print(y)\n",
    "# [ 1  4  9 16]\n",
    "print(np.power(x, 2))\n",
    "# [ 1  4  9 16]\n",
    "```\n",
    "\n",
    "\n",
    "---\n",
    "## 三角函数\n",
    "\n",
    "### numpy.sin\n",
    "### numpy.cos\n",
    "### numpy.tan\n",
    "### numpy.arcsin\n",
    "### numpy.arccos\n",
    "### numpy.arctan\n",
    "\n",
    "- `numpy.sin(x, *args, **kwargs)` Trigonometric sine, element-wise.\n",
    "- `numpy.cos(x, *args, **kwargs)` Cosine element-wise.\n",
    "- `numpy.tan(x, *args, **kwargs)` Compute tangent element-wise.\n",
    "- `numpy.arcsin(x, *args, **kwargs)` Inverse sine, element-wise.\n",
    "- `numpy.arccos(x, *args, **kwargs)` Trigonometric inverse cosine, element-wise.\n",
    "- `numpy.arctan(x, *args, **kwargs)` Trigonometric inverse tangent, element-wise.\n",
    "\n",
    "\n",
    "**通用函数**（universal function）通常叫作ufunc，它对数组中的各个元素逐一进行操作。这表明，通用函数分别处理输入数组的每个元素，生成的结果组成一个新的输出数组。输出数组的大小跟输入数组相同。\n",
    "\n",
    "三角函数等很多数学运算符合通用函数的定义，例如，计算平方根的`sqrt()`函数、用来取对数的`log()`函数和求正弦值的`sin()`函数。\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.linspace(start=0, stop=np.pi / 2, num=10)\n",
    "print(x)\n",
    "# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463\n",
    "#  1.04719755 1.22173048 1.3962634  1.57079633]\n",
    "\n",
    "y = np.sin(x)\n",
    "print(y)\n",
    "# [0.         0.17364818 0.34202014 0.5        0.64278761 0.76604444\n",
    "#  0.8660254  0.93969262 0.98480775 1.        ]\n",
    "\n",
    "z = np.arcsin(y)\n",
    "print(z)\n",
    "# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463\n",
    "#  1.04719755 1.22173048 1.3962634  1.57079633]\n",
    "\n",
    "y = np.cos(x)\n",
    "print(y)\n",
    "# [1.00000000e+00 9.84807753e-01 9.39692621e-01 8.66025404e-01\n",
    "#  7.66044443e-01 6.42787610e-01 5.00000000e-01 3.42020143e-01\n",
    "#  1.73648178e-01 6.12323400e-17]\n",
    "\n",
    "z = np.arccos(y)\n",
    "print(z)\n",
    "# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463\n",
    "#  1.04719755 1.22173048 1.3962634  1.57079633]\n",
    "\n",
    "y = np.tan(x)\n",
    "print(y)\n",
    "# [0.00000000e+00 1.76326981e-01 3.63970234e-01 5.77350269e-01\n",
    "#  8.39099631e-01 1.19175359e+00 1.73205081e+00 2.74747742e+00\n",
    "#  5.67128182e+00 1.63312394e+16]\n",
    "\n",
    "z = np.arctan(y)\n",
    "print(z)\n",
    "# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463\n",
    "#  1.04719755 1.22173048 1.3962634  1.57079633]\n",
    "```\n",
    "\n",
    "---\n",
    "## 指数和对数\n",
    "### numpy.exp\n",
    "### numpy.log\n",
    "### numpy.exp2\n",
    "### numpy.log2\n",
    "### numpy.log10\n",
    "\n",
    "- `numpy.exp(x, *args, **kwargs)` Calculate the exponential of all elements in the input array.\n",
    "- `numpy.log(x, *args, **kwargs)` Natural logarithm, element-wise.\n",
    "- `numpy.exp2(x, *args, **kwargs)` Calculate `2**p` for all `p` in the input array.\n",
    "- `numpy.log2(x, *args, **kwargs)` Base-2 logarithm of `x`.\n",
    "- `numpy.log10(x, *args, **kwargs)` Return the base 10 logarithm of the input array, element-wise.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "【例】The natural logarithm `log` is the inverse of the exponential function, so that `log(exp(x)) = x`. The natural logarithm is logarithm in base `e`.\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(1, 5)\n",
    "print(x)\n",
    "# [1 2 3 4]\n",
    "y = np.exp(x)\n",
    "print(y)\n",
    "# [ 2.71828183  7.3890561  20.08553692 54.59815003]\n",
    "z = np.log(y)\n",
    "print(z)\n",
    "# [1. 2. 3. 4.]\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "---\n",
    "## 加法函数、乘法函数\n",
    "### numpy.sum\n",
    "\n",
    "- `numpy.sum(a[, axis=None, dtype=None, out=None, …])` Sum of array elements over a given axis.\n",
    "\n",
    "通过不同的 `axis`，numpy 会沿着不同的方向进行操作：如果不设置，那么对所有的元素操作；如果`axis=0`，则沿着纵轴进行操作；`axis=1`，则沿着横轴进行操作。但这只是简单的二位数组，如果是多维的呢？可以总结为一句话：设`axis=i`，则 numpy 沿着第`i`个下标变化的方向进行操作。\n",
    "\n",
    "### numpy.cumsum\n",
    "\n",
    "- `numpy.cumsum(a, axis=None, dtype=None, out=None)` Return the cumulative sum of the elements along a given axis.\n",
    "\n",
    "**聚合函数** 是指对一组值（比如一个数组）进行操作，返回一个单一值作为结果的函数。因而，求数组所有元素之和的函数就是聚合函数。`ndarray`类实现了多个这样的函数。\n",
    "\n",
    "【例】返回给定轴上的数组元素的总和。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = np.sum(x)\n",
    "print(y)  # 575\n",
    "\n",
    "y = np.sum(x, axis=0)\n",
    "print(y)  # [105 110 115 120 125]\n",
    "\n",
    "y = np.sum(x, axis=1)\n",
    "print(y)  # [ 65  90 115 140 165]\n",
    "```\n",
    "\n",
    "\n",
    "【例】返回给定轴上的数组元素的累加和。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = np.cumsum(x)\n",
    "print(y)\n",
    "# [ 11  23  36  50  65  81  98 116 135 155 176 198 221 245 270 296 323 351\n",
    "#  380 410 441 473 506 540 575]\n",
    "\n",
    "y = np.cumsum(x, axis=0)\n",
    "print(y)\n",
    "# [[ 11  12  13  14  15]\n",
    "#  [ 27  29  31  33  35]\n",
    "#  [ 48  51  54  57  60]\n",
    "#  [ 74  78  82  86  90]\n",
    "#  [105 110 115 120 125]]\n",
    "\n",
    "y = np.cumsum(x, axis=1)\n",
    "print(y)\n",
    "# [[ 11  23  36  50  65]\n",
    "#  [ 16  33  51  70  90]\n",
    "#  [ 21  43  66  90 115]\n",
    "#  [ 26  53  81 110 140]\n",
    "#  [ 31  63  96 130 165]]\n",
    "```\n",
    "### numpy.prod 乘积\n",
    "- `numpy.prod(a[, axis=None, dtype=None, out=None, …])` Return the product of array elements over a given axis.\n",
    "\n",
    "### numpy.cumprod 累乘\n",
    "- `numpy.cumprod(a, axis=None, dtype=None, out=None)` Return the cumulative product of elements along a given axis.\n",
    "\n",
    "【例】返回给定轴上数组元素的乘积。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = np.prod(x)\n",
    "print(y)  # 788529152\n",
    "\n",
    "y = np.prod(x, axis=0)\n",
    "print(y)\n",
    "# [2978976 3877632 4972968 6294624 7875000]\n",
    "\n",
    "y = np.prod(x, axis=1)\n",
    "print(y)\n",
    "# [  360360  1860480  6375600 17100720 38955840]\n",
    "```\n",
    "\n",
    "\n",
    "【例】返回给定轴上数组元素的累乘。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = np.cumprod(x)\n",
    "print(y)\n",
    "# [         11         132        1716       24024      360360     5765760\n",
    "#     98017920  1764322560  -837609728   427674624   391232512    17180672\n",
    "#    395155456   893796352   870072320  1147043840   905412608  -418250752\n",
    "#    755630080  1194065920 -1638662144  -897581056   444596224 -2063597568\n",
    "#    788529152]\n",
    "\n",
    "y = np.cumprod(x, axis=0)\n",
    "print(y)\n",
    "# [[     11      12      13      14      15]\n",
    "#  [    176     204     234     266     300]\n",
    "#  [   3696    4488    5382    6384    7500]\n",
    "#  [  96096  121176  150696  185136  225000]\n",
    "#  [2978976 3877632 4972968 6294624 7875000]]\n",
    "\n",
    "y = np.cumprod(x, axis=1)\n",
    "print(y)\n",
    "# [[      11      132     1716    24024   360360]\n",
    "#  [      16      272     4896    93024  1860480]\n",
    "#  [      21      462    10626   255024  6375600]\n",
    "#  [      26      702    19656   570024 17100720]\n",
    "#  [      31      992    32736  1113024 38955840]]\n",
    "```\n",
    "### numpy.diff 差值\n",
    "\n",
    "- `numpy.diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue)` Calculate the n-th discrete difference along the given axis.\n",
    "    - a：输入矩阵\n",
    "    - n：可选，代表要执行几次差值\n",
    "    - axis：默认是最后一个\n",
    "\n",
    "\n",
    "The first difference is given by `out[i] = a[i+1] - a[i]` along the given axis, higher differences are calculated by using `diff` recursively.\n",
    "\n",
    "【例】沿着指定轴计算第N维的离散差值。\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "A = np.arange(2, 14).reshape((3, 4))\n",
    "A[1, 1] = 8\n",
    "print(A)\n",
    "# [[ 2  3  4  5]\n",
    "#  [ 6  8  8  9]\n",
    "#  [10 11 12 13]]\n",
    "print(np.diff(A))\n",
    "# [[1 1 1]\n",
    "#  [2 0 1]\n",
    "#  [1 1 1]]\n",
    "print(np.diff(A, axis=0))\n",
    "# [[4 5 4 4]\n",
    "#  [4 3 4 4]]\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "---\n",
    "## 四舍五入\n",
    "### numpy.around 舍入\n",
    "\n",
    "- `numpy.around(a, decimals=0, out=None)` Evenly round to the given number of decimals.\n",
    "\n",
    "\n",
    "【例】将数组舍入到给定的小数位数。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.random.rand(3, 3) * 10\n",
    "print(x)\n",
    "# [[6.59144457 3.78566113 8.15321227]\n",
    "#  [1.68241475 3.78753332 7.68886328]\n",
    "#  [2.84255822 9.58106727 7.86678037]]\n",
    "\n",
    "y = np.around(x)\n",
    "print(y)\n",
    "# [[ 7.  4.  8.]\n",
    "#  [ 2.  4.  8.]\n",
    "#  [ 3. 10.  8.]]\n",
    "\n",
    "y = np.around(x, decimals=2)\n",
    "print(y)\n",
    "# [[6.59 3.79 8.15]\n",
    "#  [1.68 3.79 7.69]\n",
    "#  [2.84 9.58 7.87]]\n",
    "```\n",
    "### numpy.ceil 上限\n",
    "### numpy.floor 下限\n",
    "\n",
    "- `numpy.ceil(x, *args, **kwargs)` Return the ceiling of the input, element-wise.\n",
    "- `numpy.floor(x, *args, **kwargs)` Return the floor of the input, element-wise.\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.random.rand(3, 3) * 10\n",
    "print(x)\n",
    "# [[0.67847795 1.33073923 4.53920122]\n",
    "#  [7.55724676 5.88854047 2.65502046]\n",
    "#  [8.67640444 8.80110812 5.97528726]]\n",
    "\n",
    "y = np.ceil(x)\n",
    "print(y)\n",
    "# [[1. 2. 5.]\n",
    "#  [8. 6. 3.]\n",
    "#  [9. 9. 6.]]\n",
    "\n",
    "y = np.floor(x)\n",
    "print(y)\n",
    "# [[0. 1. 4.]\n",
    "#  [7. 5. 2.]\n",
    "#  [8. 8. 5.]]\n",
    "```\n",
    "\n",
    "---\n",
    "## 杂项\n",
    "\n",
    "### numpy.clip 裁剪\n",
    "\n",
    "- `numpy.clip(a, a_min, a_max, out=None, **kwargs):` Clip (limit) the values in an array.\n",
    "\n",
    "Given an interval, values outside the interval are clipped to the interval edges.  For example, if an interval of `[0, 1]` is specified, values smaller than 0 become 0, and values larger than 1 become 1.\n",
    "\n",
    "\n",
    "【例】裁剪（限制）数组中的值。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = np.clip(x, a_min=20, a_max=30)\n",
    "print(y)\n",
    "# [[20 20 20 20 20]\n",
    "#  [20 20 20 20 20]\n",
    "#  [21 22 23 24 25]\n",
    "#  [26 27 28 29 30]\n",
    "#  [30 30 30 30 30]]\n",
    "```\n",
    "### numpy.absolute 绝对值\n",
    "### numpy.abs\n",
    "\n",
    "- `numpy.absolute(x, *args, **kwargs)` Calculate the absolute value element-wise. \n",
    "- `numpy.abs(x, *args, **kwargs)` is a shorthand for this function.\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(-5, 5)\n",
    "print(x)\n",
    "# [-5 -4 -3 -2 -1  0  1  2  3  4]\n",
    "\n",
    "y = np.abs(x)\n",
    "print(y)\n",
    "# [5 4 3 2 1 0 1 2 3 4]\n",
    "\n",
    "y = np.absolute(x)\n",
    "print(y)\n",
    "# [5 4 3 2 1 0 1 2 3 4]\n",
    "```\n",
    "### numpy.sign 返回数字符号的逐元素指示\n",
    "- `numpy.sign(x, *args, **kwargs)` Returns an element-wise indication of the sign of a number.\n",
    "\n",
    "【例】\n",
    "\n",
    "```python\n",
    "x = np.arange(-5, 5)\n",
    "print(x)\n",
    "#[-5 -4 -3 -2 -1  0  1  2  3  4]\n",
    "print(np.sign(x))\n",
    "#[-1 -1 -1 -1 -1  0  1  1  1  1]\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "---\n",
    "**参考文献**\n",
    "- https://mp.weixin.qq.com/s/RWsGvvmw4ptf7d8zPIDEJw\n",
    "- https://blog.csdn.net/hanshuobest/article/details/78558826?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-30T17:00:33.199734Z",
     "start_time": "2020-08-30T17:00:33.194782Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-5 -4 -3 -2 -1  0  1  2  3  4]\n",
      "[-1 -1 -1 -1 -1  0  1  1  1  1]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(-5, 5)\n",
    "print(x)\n",
    "print(np.sign(x))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python35",
   "language": "python",
   "name": "python35"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "307.2px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
